#ifndef __GAME_H
#define __GAME_H

#include "stm32f30x_conf.h"

// general definitions
#define LED_IGNORE  (0x0) // 0b00
#define LED_ENABLE  (0x1) // 0b01
#define LED_DISABLE (0x2) // 0b10
#define LED_TOGGLE  (0x3) // 0b11

#define MAX_X 16
#define MAX_Y 16
#define MAX_CONTROLLER_X 8
#define MAX_CONTROLLER_Y 8
#define MAX_LIVES 10

#define DEFAULT_MAX_FRAMES 12
#define DEFAULT_MAX_MOVES 5

#define GO_SCREEN_OFFSET_Y 3
#define GO_SCREEN_SIZE 11
#define GO_SCREEN_FLASHING_PERIOD 4096
#define GO_SCREEN_FLASHING_COMPARE 2048

#define SAVED_ADC_CONVERSION_VALUES 3

// structure definitions
typedef struct GameObject {
    int8_t ulx, uly;
    int8_t lrx, lry;
} GameObject;

typedef struct Node {
    GameObject obj;
    struct Node *prev;
    struct Node *next;
} Node;

typedef struct LinkedList {
    // manages first and last
    Node *first;
    uint8_t empty;
} LinkedList;

// globals
extern LinkedList list;
extern uint8_t framebuffer[16][16];
//extern uint8_t activations[16][16];
extern uint32_t frames;
extern uint32_t framesMax;
extern uint8_t moves;
extern uint8_t movesMax;
extern uint8_t shipSize;
extern uint8_t lives;
extern uint8_t conversionValues[SAVED_ADC_CONVERSION_VALUES];

// game over screen
extern const uint16_t GOScreen[GO_SCREEN_SIZE];

// game function definitions
/**
  * @brief Initializes all globals and other primitives necessary for the game.
 */
void gameInit(void);

/**
  * @brief Updates all globals and other primitives necessary for the game.
 */
void gameUpdate(void);

/**
  * @brief Takes an activation by coordinates and checks if a collision
  *        occurred, removes game objects if hit.
  * @param y y coordinate of activation
  * @param x x coordinate of activation
 */
void checkCollision(int8_t y, int8_t x);

/**
  * @brief Routine that should be called after the main game was terminated
  *        by the losing condition, renders a predefined game over texture.
 */
void renderGameOver(void);

// utility function definitions
/**
  * @brief creates a game object structure and initializes it with given
  *        parameters.
  * @param x x coordinate of game object
  * @param y y coordinate of game object
  * @param w width of game object
  * @param h height of game object
 */
GameObject createGameObject(int8_t x, int8_t y, uint8_t w, uint8_t h);


/**
  * @brief creates a node structure and initializes it with a given game
  *        object.
  * @param obj game object structure already initialized
 */
Node *createNode(GameObject obj);

/**
  * @brief creates a linked list structure and initializes it.
 */
void createLinkedList(void);

/**
  * @brief Takes a list and adds a game object to it, checking typical list
  *        constraints.
  * @param list pointer to initialized list to add obj to
  * @param obj game object to add to list
 */
void addToList(LinkedList* list, GameObject obj);

/**
  * @brief Takes a list and adds a game object to it, checking typical list
  *        constraints.
  * @param list pointer to initialized list to remove node from
  * @param node pointer to node that should be removed
 */
void removeFromList(LinkedList* list, Node *node);

#endif /* __GAME_H */
